package com.bsoft.gol.hbs.utils;

import ctd.controller.exception.ControllerException;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalTime;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;

public class DateUtils {

    private static SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");



    public static String toStringForYYYYMMdd(Date date){
       return sdf.format(date);
    }

    public static String toStringForYYYYMMddHHmmss(Date date){
        return sdf1.format(date);
    }

    /**
     * 功能：计算日期
     * 作者：chendw
     * 时间：2010-3-4 下午07:47:31
     * 版本：
     * 参数： 日期基值  date
     * 		  计算类型  type 如 Calendar.YEAR、Calendar.MONTH
     * 		  计算偏值  num
     * @return
     */
    public static Date caclDate(Date date, int type, int num) {
        Calendar C = Calendar.getInstance();
        C.setTime(date);
        C.add(type, num);
        return C.getTime();
    }

    public static String toString(Date date,String format){
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(date);
    }

    public static Date toDate(String date){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date d=null;
        try {
            d = sdf.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return d;
    }

    public static Date toDateForYYYYMMddHHmmss(String date){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        if(date == null){
           return null;
        }
        Date d=null;
        try {
            d = sdf.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return d;
    }


    public static  Date toDate(Date date)
    {
        String str = toString(date, "yyyy-MM-dd HH:mm:ss");
        return toDate(str);
    }

    public static Date toDate(String date,String format){
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        Date d=null;
        try {
            d = sdf.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return d;
    }

    public static Date toDateFromIdCard(String idCardNo) throws ControllerException {
        String birthdayString = "";
        if(idCardNo.length()==18){
            birthdayString = idCardNo.substring(6,14);
        }else if(idCardNo.length()==15){
            birthdayString = "19"+ idCardNo.substring(6,12);
        }else {
            throw new ControllerException("证件号码格式不正确");
        }
        return toDate(birthdayString,"yyyyMMdd");
    }

    public static String toTime(Date date){
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
        String dateString="";

        dateString = sdf.format(date);

        return dateString;
    }

    public static String toTimeHHmm(Date date){
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
        String dateString="";

        dateString = sdf.format(date);

        return dateString;
    }

    public static String toTimeYY(Date date){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String dateString="";

        dateString = sdf.format(date);

        return dateString;
    }

    public static String toallTime(Date date){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateString="";

        dateString = sdf.format(date);

        return dateString;
    }



    public static Date dateAdd(Date date){
        Calendar calendar   =   new GregorianCalendar();
        calendar.setTime(date);
        calendar.add(Calendar.DATE,1);
        date=calendar.getTime();
        return date;
    }

    public static Date dateAdd(Date date,int ai){
        Calendar   calendar   =   new   GregorianCalendar();
        calendar.setTime(date);
        calendar.add(Calendar.DATE,ai);
        date=calendar.getTime();
        return date;
    }

    public static String getTimeStep(Date date){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        return simpleDateFormat.format(date);
    }

    public static Long getTimeMillis(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.getTimeInMillis();
    }

    /**
     * @description: 获取系统时间和指定时间的毫秒时间差
     * @author: chenJij@bsoft.com.cn
     * @date: 2019/10/17 09:58
     */
    public static Long getCountTimeMillis(Date time1, Date time2) throws ParseException {
        if(null==time1){
            return 0L;
        }
        if(null == time2){
            return 0L;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time1);
        Long caTime1 = calendar.getTimeInMillis();
        calendar.setTime(time2);
        Long caTime2 = calendar.getTimeInMillis();
        Long countTimeMillis = caTime2 - caTime1;
        return countTimeMillis>=0?countTimeMillis:0;
    }

    /**
     * @description: 获取系统时间和指定时间的毫秒时间差
     * @author: chenJij@bsoft.com.cn
     * @date: 2019/10/17 09:58
     */
    public static Integer getAgesByCountTimeMillis(Date time1, Date time2) throws ParseException {
        if(null==time1){
            return 0;
        }
        if(null == time2){
            return 0;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time1);
        Long caTime1 = calendar.getTimeInMillis();

        Calendar calendar2 = Calendar.getInstance();
        calendar2.setTime(time2);
        Long caTime2 = calendar2.getTimeInMillis();

        Long countTimeMillis = caTime2 - caTime1;
        countTimeMillis = countTimeMillis>=0?countTimeMillis:0;
        BigDecimal age =new BigDecimal(countTimeMillis);
        age = age.divide(new BigDecimal(1000),0,BigDecimal.ROUND_UP);
        age = age.divide(new BigDecimal(3600),0,BigDecimal.ROUND_UP);
        age = age.divide(new BigDecimal(24),0,BigDecimal.ROUND_UP);
        age = age.divide(new BigDecimal(365),0,BigDecimal.ROUND_UP);
        return age.intValue();
    }

    /**
     * @description: 获取系统时间和指定时间的天数差
     * @author: chenJij@bsoft.com.cn
     * @date: 2019/10/17 09:58
     */
    public static Integer getDaysByCountTimeMillis(Date time1, Date time2) throws ParseException {
        if(null==time1){
            return 0;
        }
        if(null == time2){
            return 0;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time1);
        Long caTime1 = calendar.getTimeInMillis();

        Calendar calendar2 = Calendar.getInstance();
        calendar2.setTime(time2);
        Long caTime2 = calendar2.getTimeInMillis();

        Long countTimeMillis = caTime2 - caTime1;
        countTimeMillis = countTimeMillis>=0?countTimeMillis:0;
        BigDecimal age =new BigDecimal(countTimeMillis);
        age = age.divide(new BigDecimal(1000),0,BigDecimal.ROUND_UP);
        age = age.divide(new BigDecimal(3600),0,BigDecimal.ROUND_UP);
        age = age.divide(new BigDecimal(24),0,BigDecimal.ROUND_UP);
        return age.intValue();
    }


    /**
     * 判断是否在某个时间范围内
     * @param startTime 范围开始时间  格式为"xx:xx"
     * @param endTime   范围结束时间  格式为"xx:xx"
     * @param nowHour   当前小时
     * @param nowMinute 当前分钟
     * @return  true/false
     */
    public static boolean isTimeRange(String startTime, String endTime, int nowHour, int nowMinute) {
        LocalTime nowTime = LocalTime.of(nowHour, nowMinute);
        int startHour = getHourOrMinute(startTime, true);
        int startMinute = getHourOrMinute(startTime, false);
        LocalTime startTimeLocal = LocalTime.of(startHour, startMinute);
        int endHour = getHourOrMinute(endTime, true);
        int endMinute = getHourOrMinute(endTime, false);
        LocalTime endTimeLocal = LocalTime.of(endHour, endMinute);
        if (nowTime.isAfter(startTimeLocal) && endTimeLocal.isAfter(nowTime)) {
            return true;
        } else if (nowTime.equals(startTimeLocal) || endTimeLocal.equals(nowTime)) {
            return true;
        }
        return false;

    }
    /**
     * 针对str格式的时间做转换 格式为"xx:xx"
     * @param time  传入的时间
     * @param hour  true：返回小时；false：返回分钟
     * @return  当前小时或分钟
     */
    private static int getHourOrMinute(String time,boolean hour) {
        if (hour) {
            return Integer.parseInt(time.substring(0, time.indexOf(":")));
        } else {
            return Integer.parseInt(time.substring(time.indexOf(":") + 1));
        }

    }
    /**
     * @description: 获取系统时间和指定时间的毫秒时间差
     * @author: chenJij@bsoft.com.cn
     * @date: 2019/10/17 09:58
     */
    public static Long countTimeMillis(Long currentTimeMillis,Date date){
        if(null==date){
            return 0L;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        Long calendarTimeMillis = calendar.getTimeInMillis();
        Long countTimeMillis = calendarTimeMillis - currentTimeMillis ;
        return countTimeMillis>=0?countTimeMillis:0;
    }

    /**
     * @description: 日期转星期
     * @author: chenJij@bsoft.com.cn
     * @date: 2019/10/22 13:53
     */
    public static String dateToWeek(String datetime) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        String[] weekDays = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };
        Calendar cal = Calendar.getInstance(); // 获得一个日历
        Date datet = null;
        try {
            datet = format.parse(datetime);
            cal.setTime(datet);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1; // 指示一个星期中的某天。
        if (w < 0){
            w = 0;
        }
        return weekDays[w];
    }

    public static String dateToWeekPT(String datetime) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        String[] weekDays = { "周日", "周一", "周二", "周三", "周四", "周五", "周六" };
        Calendar cal = Calendar.getInstance(); // 获得一个日历
        Date datet = null;
        try {
            datet = format.parse(datetime);
            cal.setTime(datet);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1; // 指示一个星期中的某天。
        if (w < 0){
            w = 0;
        }
        return weekDays[w];
    }


//    public static void main(String[] args) {
//        String date = "2020-02-20";
//        Boolean flag = null;
//        try {
//            flag = DateUtils.planOverTime(date,"13:00",(byte)2);
//        } catch (ParseException e) {
//            e.printStackTrace();
//        }
//        System.out.println(flag);
//        System.out.println(dateToWeek("2019-10-22"));
//    }


    public static Date getThisWeekMonday(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        // 获得当前日期是一个星期的第几天
        int dayWeek = cal.get(Calendar.DAY_OF_WEEK);
        if (1 == dayWeek) {
            cal.add(Calendar.DAY_OF_MONTH, -1);
        }
        // 设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        // 获得当前日期是一个星期的第几天
        int day = cal.get(Calendar.DAY_OF_WEEK);
        // 根据日历的规则，给当前日期减去星期几与一个星期第一天的差值
        cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day);
        return cal.getTime();
    }

    public static  Date toMonDayDate(Date date){
        Date new_date = getThisWeekMonday(date);
        String str=toString(new_date,"yyyy-MM-dd HH:mm:ss");
        return toDate(str);
    }

    public static Date toMonDayDate(String date){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date d=null;
        try {
            d = sdf.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return toMonDayDate(d);
    }


    //判断时间差
    public static boolean betweenT1andT2(Date date1,Date date2){
        String time1 = sdf1.format(date1);
        String time2 = sdf1.format(date2);
        boolean flag =false;

        try {
            long a = sdf1.parse(time1).getTime();
            long b = sdf1.parse(time2).getTime();

            if(a<=b){
                flag = true;
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return flag;
    }

    //判断时间差
    public static boolean betweenD1andD2(Date date1,Date date2){
            boolean flag =false;
            long a = date1.getTime();
            long b = date2.getTime();
            if(a<=b){
               long c=b-a;
               if(c<86400*1000){
                   flag = true;
               }
            }
            if(a>b){
                flag = true;
            }
        return flag;
    }




    public static int getAgeByBirth(Date birthDay){
        try {
            int age = 0;
            Calendar cal = Calendar.getInstance();
            if (cal.before(birthDay)) { //出生日期晚于当前时间，无法计算
                throw new IllegalArgumentException(
                        "The birthDay is before Now.It's unbelievable!");
            }
            int yearNow = cal.get(Calendar.YEAR);  //当前年份
            int monthNow = cal.get(Calendar.MONTH);  //当前月份
            int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH); //当前日期
            cal.setTime(birthDay);
            int yearBirth = cal.get(Calendar.YEAR);
            int monthBirth = cal.get(Calendar.MONTH);
            int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);
            age = yearNow - yearBirth;   //计算整岁数
            if (monthNow <= monthBirth) {
                if (monthNow == monthBirth) {
                    if (dayOfMonthNow < dayOfMonthBirth) {
                        age--;//当前日期在生日之前，年龄减一
                    }
                } else {
                    age--;//当前月份在生日之前，年龄减一
                }
            }
            return age;
        }catch (Exception e){
           e.printStackTrace();
        }
        return 0;
    }


//    public static boolean getscheList(Date date,byte i){
//        Boolean flag=false;
//        SimpleDateFormat sdfam = new SimpleDateFormat("yyyy-MM-dd 12:00:00");
//        SimpleDateFormat sdfpm = new SimpleDateFormat("yyyy-MM-dd 18:00:00");
//        SimpleDateFormat sdfmm = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
//        String amTime =  sdfam.format(new Date());
//        Date aDate = DateUtils.toDateForYYYYMMddHHmmss(amTime);
//        String pmTime =  sdfpm.format(new Date());
//        Date pmDate = DateUtils.toDateForYYYYMMddHHmmss(pmTime);
//        String mmTime =  sdfmm.format(new Date());
//        Date mmDate = DateUtils.toDateForYYYYMMddHHmmss(mmTime);
//        try {
//            if(i == 1){
//                Long time1 = DateUtils.getCountTimeMillis(aDate,date);
//                if(time1>0){
//                    flag=true;
//                }
//            }else if(i==2){
//                Long time2 = DateUtils.getCountTimeMillis(pmDate,date);
//                if(time2>0){
//                    flag=true;
//                }
//            }else if(i==3){
//                Long time3 = DateUtils.getCountTimeMillis(date,mmDate);
//                if(time3>0){
//                    flag=true;
//                }
//            }
//
//        } catch (ParseException e) {
//            e.printStackTrace();
//        }
//        return flag;
//    }

    public static boolean planOverTime(String schedulingDate,String startTime,String endTime,byte planTime) throws ParseException {
        boolean flag = false;
        Date nowTime = sdf1.parse(sdf1.format(new Date()));
        Date nowTime_bf= sdf.parse(sdf.format(new Date()));
        Date schtime = sdf.parse(schedulingDate);
        Date scheTime = sdf1.parse(schedulingDate+" "+startTime+":00");
        Date scheEndTime = sdf1.parse(schedulingDate+" "+endTime+":00");
        Long time  = DateUtils.getCountTimeMillis(nowTime_bf,schtime);
        if(time >0){
            flag =true;
        }else if(time ==0){
            if(1==planTime){ //上午
                long time1 = nowTime.getTime();
                long time2 = scheTime.getTime();
                long time3 = scheEndTime.getTime();
                if(time2>time1 || (time3>time1&&time2<=time1)){
                    flag= true;
                }
            }else if(2==planTime){//下午
                long time1 = nowTime.getTime();
                long time2 = scheTime.getTime();
                long time3 = scheEndTime.getTime();
                if(time2>time1 || (time3>time1&&time2<=time1)){
                    flag= true;
                }
            }else if(3==planTime){
                long time1 = nowTime.getTime();
                long time2 = scheTime.getTime();
                long time3 = scheEndTime.getTime();
                if(time2>time1 || (time3>time1&&time2<=time1)){
                    flag= true;
                }
            }else{
                return flag;
            }
        }
        return flag;
    }

    /**
     * @description: 计算时间差并转为天时分秒
     * @author: chenJij@bsoft.com.cn
     * @date: 2020/2/21 18:25
     */
    public static String countDays(Date begin, Date end){
        try {
            long date = end.getTime() - begin.getTime();
            if(date>0){
                long day = date / (1000 * 60 * 60 * 24);
                long hour = (date / (1000 * 60 * 60) - day * 24);
                long min = ((date / (60 * 1000)) - day * 24 * 60 - hour * 60);
                long s = (date/1000 - day*24*60*60 - hour*60*60 - min*60);

                StringBuffer stringBuffer = new StringBuffer();

                if(day>0){
                    stringBuffer.append(day+"天");
                    if(hour>0){
                        stringBuffer.append(hour+"小时");
                        if(min>0){
                            stringBuffer.append(min+"分钟");
                        }
                    }else {
                        if(min>0){
                            stringBuffer.append(min+"分钟");
                        }
                    }
                }else if(hour>0){
                    stringBuffer.append(hour+"小时");
                    if(min>0){
                        stringBuffer.append(min+"分钟");
                    }
                }else if(min>0){
                    stringBuffer.append(min+"分钟");
                }
                return stringBuffer.toString();
            }else {
                return "";
            }

        }catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 判断当前时间是否在指定区域时间段内
     * @param nowTime
     * @param startTime
     * @param endTime
     * @return
     */
    public static boolean isEffectiveDate(Date nowTime, Date startTime, Date endTime) {
        if (nowTime.getTime() == startTime.getTime()
                || nowTime.getTime() == endTime.getTime()) {
            return true;
        }

        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);

        Calendar begin = Calendar.getInstance();
        begin.setTime(startTime);

        Calendar end = Calendar.getInstance();
        end.setTime(endTime);

        if (date.after(begin) && date.before(end)) {
            return true;
        } else {
            return false;
        }
    }

    public static Date toDate(long mills){
        Date date = new Date(mills);
        return date;
    }
    public static String dateFormate(Date date, String formate) {
        if (date != null) {
            SimpleDateFormat sdf = new SimpleDateFormat(formate);
            return sdf.format(date);
        } else {
            return null;
        }
    }

    public static Date dateFormate(String date, String formate) {
        if (date != null) {
            SimpleDateFormat sdf = new SimpleDateFormat(formate);

            try {
                return sdf.parse(date);
            } catch (ParseException var4) {
                var4.printStackTrace();
                return null;
            }
        } else {
            return null;
        }
    }


    public static void main(String[] args) {
        String schDate = "2020-03-06";
        String stime = "07:00";
        String endTime="12:00";
        Byte flag=1;
        boolean fa = false;
        try {
             fa = DateUtils.planOverTime(schDate,stime,endTime,flag);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        System.out.println(fa);

    }
    /**
     * 获取上周周几的日期,默认一周从周一开始
     * @param dayOfWeek
     * @param weekOffset
     * @return
     */
    public static Date getDayOfWeek(int dayOfWeek,int weekOffset){
        return getDayOfWeeks(Calendar.MONDAY,dayOfWeek,weekOffset);
    }

    /**
     * 获取上(下)周周几的日期
     * @param firstDayOfWeek {@link Calendar}
     * 值范围 <code>SUNDAY</code>,
     * <code>MONDAY</code>, <code>TUESDAY</code>, <code>WEDNESDAY</code>,
     * <code>THURSDAY</code>, <code>FRIDAY</code>, and <code>SATURDAY</code>
     * @param dayOfWeek {@link Calendar}
     * @param weekOffset  周偏移，上周为-1，本周为0，下周为1，以此类推
     * @return
     */
    public static Date getDayOfWeeks(int firstDayOfWeek,int dayOfWeek,int weekOffset){
        if(dayOfWeek>Calendar.SATURDAY || dayOfWeek<Calendar.SUNDAY){
            return null;
        }
        if(firstDayOfWeek>Calendar.SATURDAY || firstDayOfWeek < Calendar.SUNDAY){
            return null;
        }
        Calendar date=Calendar.getInstance(Locale.CHINA);
        date.setFirstDayOfWeek(firstDayOfWeek);
        //周数减一，即上周
        date.add(Calendar.WEEK_OF_MONTH,weekOffset);
        //日子设为周几
        date.set(Calendar.DAY_OF_WEEK, dayOfWeek);
        //时分秒全部置0
        date.set(Calendar.HOUR_OF_DAY, 0);
        date.set(Calendar.MINUTE, 0);
        date.set(Calendar.SECOND, 0);
        date.set(Calendar.MILLISECOND, 0);
        return date.getTime();
    }

    /**
     * 时间减去固定月数
     * @param time 计算的时间
     * @param month 减去的月数
     * @return 时间
     */
    public static String calculateTime(Date time,int month){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar cal = Calendar.getInstance();
        cal.setTime(time);
        cal.add(Calendar.MONTH, -month);
        String newTime = sdf.format(cal.getTime());
        return newTime;
    }

    /**
     * 求两个日期相差天数
     *
     * @param sd
     *            起始日期，格式yyyy-MM-dd
     * @param ed
     *            终止日期，格式yyyy-MM-dd
     * @return 两个日期相差天数
     */
    public static long getBetweenDay(String sd, String ed) {
        return ((java.sql.Date.valueOf(ed)).getTime() - (java.sql.Date.valueOf(sd)).getTime()) / (3600 * 24 * 1000);
    }

    /**
     * 求两个日期相差天数
     *
     * @param sd
     *            起始日期，格式yyyy-MM-dd
     * @param ed
     *            终止日期，格式yyyy-MM-dd
     * @return 两个日期相差天数
     */
    public static long getBetweenDay(Date sd, Date ed) {
        return (ed.getTime() - sd.getTime()) / (3600 * 24 * 1000);
    }

    public static int getBetweenDay(Date lastDate) {
        int between = Integer.MIN_VALUE;
        if (lastDate != null) {
            Calendar cnow = Calendar.getInstance();
            Calendar clast = Calendar.getInstance();
            clast.setTime(lastDate);
            between = getBetweenTime(clast, cnow, Calendar.DATE);
        }
        return between;
    }

    /**
     * 返回两个日期的时间差，返回的时间差格式可以是: Calendar.YEAR, Calendar.MONTH, Calendar.DATE
     * 注意：该功能采用递归的方法，效率还有待解决，如果两个时间之差较大，而要求返回的时间格式又很小，这时效率就很差
     * 但此方法在要求精度较高的情况下比较有效，如求月份差的时候就比较准确，考虑到了各种情况．如闰月，闰年
     *
     * @param earlyDate
     * @param lateDate
     * @param returnTimeFormat
     * @return time
     */
    public static int getBetweenTime(Calendar earlyDate, Calendar lateDate, int returnTimeFormat) {
        earlyDate = (Calendar) earlyDate.clone();
        lateDate = (Calendar) lateDate.clone();
        int time = 0;
        while (earlyDate.before(lateDate)) {
            earlyDate.add(returnTimeFormat, 1);
            time++;
        }
        return time;
    }

}
